package main

import (
	"fmt"
	"math"
)

/**
 * @author: guangcheng
 * @date:   2020/11/21 18:08
 * @version  V1.0
 * @description:
 *
 */
func main() {

	var p Person
	p.Name = "mulan"
	/*
		person.Name= jack
		p.Name= mulan
		传过去的是副本值, 不会对自己有影响
	*/
	p.test()
	fmt.Println("p.Name=", p.Name)

	p.youAreGoodMan()

	sum := p.calSum(10, 20)
	fmt.Println("sum=", sum)

	//计算圆形面积
	var c1 Circle
	c1.Radius = 2.1
	area := c1.getArea()
	fmt.Println("area=", area)

	/**
	person.Name= jack
	p.Name= mulan
	mulan 你是个好人,我们不合适
	sum= 30
	area= 13.854423602330987
	main c1 address=0xc0000a2058
	getArea2 circle address=0xc0000a2058
	area3= 13.854423602330987
	getArea2 circle address=0xc0000a2058
	area2= 13.854423602330987
	*/
	fmt.Printf("main c1 address=%p\n", &c1)
	//标准调用方式
	area3 := (&c1).getArea2()
	fmt.Println("area3=", area3)
	//可以简写
	area2 := c1.getArea2()
	fmt.Println("area2=", area2)

}

type Person struct {
	Name string
}

//只能由该类型的实例变量调用, 传入的是副本值, 所有修改不会影响到原值
func (person Person) test() {
	person.Name = "jack"
	fmt.Println("person.Name=", person.Name)
}

//person这个参数可以不使用
func (person Person) calSum(a int, b int) int {
	return a + b
}

func (person Person) youAreGoodMan() {
	fmt.Printf("%v 你是个好人,我们不合适\n", person.Name)
}

type Circle struct {
	Radius float64
}

func (circle Circle) getArea() float64 {
	return math.Pi * circle.Radius * circle.Radius
}

//此时前置约束参数是一个指针, 内存布局截然不同于上面
func (circle *Circle) getArea2() float64 {
	fmt.Printf("getArea2 circle address=%p\n", circle)
	//return math.Pi * (*circle).Radius * (*circle).Radius
	//编译器优化, 可以简写
	return math.Pi * circle.Radius * circle.Radius
}
